就決定是你了!去吧,吾等之鼠輩。
圖片來源:YouTube
本篇續前日,紀錄鼠輩之不可思議事件:mousemove,並利用mousedown、mouseup與mousemove之事件組合實作一簡易之操術練習。
此事件於鼠輩移動時發生。事件觸發頻率會依照裝置、介面而有所不同。事件應於鼠輩移動時連續且持續地發生,而非移動一次、觸發一次。
規範原文:
The frequency rate of events while the pointing device is moved is implementation-, device-, and platform-specific, but multiple consecutive mousemove events SHOULD be fired for sustained pointer-device movement, rather than a single event for each instance of mouse movement.
以下簡單示例針對方框元素進行mousemove事件之觀測,並將函式之術設定為印出此事件,以觀察事件觸發之頻率:
const square = document.querySelector(".square");
function printEvent(event) {
  console.log(event);
}
square.addEventListener("mousemove", printEvent);
分段註釋如下:
選取方框元素。
const square = document.querySelector(".square");
定義函式之術名printEvent,術式內容為印出觸發之事件。
function printEvent(event) {
  console.log(event);
}
設定事件觀測器,觀測方框元素是否發生mousemove事件,以啟動函式之術。
square.addEventListener("mousemove", printEvent);
可見鼠輩於方框上移動時,會持續觸發mousemove事件。
紀錄者之愛鼠小七先前卒因於腫瘤之惡襲,說時遲那時快,壽命不及兩秋,就鼠掉了。為了時常追思與祈福,可以mousedown、mousemove與mouseup之組合,建立電訊號版本之簡易祭鼠儀式:
const square = document.querySelector(".square");
const seven = document.querySelector(".square img");
const totalLove = document.querySelector(".total-love");
let isPressed = false;
let loveValue = 0;
function touchSeven(event) {
  isPressed = true;
  event.preventDefault();
}
function showLoveBubble(node, event) {
  const x = event.offsetX;
  const y = event.offsetY - 70;
  const love = document.createElement("span");
  love.classList.add("love");
  love.textContent = "♥";
  node.insertBefore(love, node.firstChild);
  love.style.transition = `opacity 0.5s`;
  love.style.transform = `translate(${x}px, ${y}px)`;
  love.style.opacity = 1;
  setTimeout(() => {
    love.style.transition = `opacity 0.5s, transform 0.3s`;
    love.style.transform = `translate(${x}px, ${y - 10}px)`;
    love.style.opacity = 0;
  }, 500);
  setTimeout(() => {
    love.remove();
  }, 1000);
}
function giveLove(event) {
  const reduceCondition = Math.round(event.timeStamp) % 10 === 0;
  if (isPressed === true && reduceCondition) {
    showLoveBubble(square, event);
    loveValue++;
  }
}
function getTotalLove() {
  isPressed = false;
  totalLove.textContent = `目前功德量: ${loveValue}點`;
}
seven.addEventListener("mousedown", touchSeven);
seven.addEventListener("mousemove", giveLove);
seven.addEventListener("mouseup", getTotalLove);
分段註釋如下:
選取所需之元素,包括方框、吾之愛鼠小七遺照、總功德量顯示處。
const square = document.querySelector(".square");
const seven = document.querySelector(".square img");
const totalLove = document.querySelector(".total-love");
設定三觀測器,對於愛鼠遺照元素觀測mousedown、mousemove與mouseup三事件,期望當鼠輩點按時發生mousedown事件以觸碰鼠、鼠輩移動時發生mousemove事件以給予愛、放開鼠輩點按時發生mouseup事件以得到總功德量。
seven.addEventListener("mousedown", touchSeven);
seven.addEventListener("mousemove", giveLove);
seven.addEventListener("mouseup", getTotalLove);
定義函式之術,各名為touchSeven、giveLove、getTotalLove,內容分別為觸碰鼠、給予愛、得到總功德量。
定義變數isPressed初始值為false,當鼠輩點按時更改為true,以便紀錄鼠輩點按之狀態。
另因mousedown事件發生時有預設行為,例如拖拉操作、文字選取等,為了取消預設行為,設定event.preventDefault();。
let isPressed = false;
function touchSeven(event) {
  isPressed = true;
  event.preventDefault();
}
定義功德量變數loveValue初始值為0,當發生mousemove事件時視為給予一次愛,可使功德量增加1點。showLoveBubble(square, event);loveValue++;
然而如同先前之紀錄,mousemove事件發生頻率過高,因此紀錄者嘗試使用條件控制以降低給予愛心之頻率。且鼠輩必須處於點按之狀態才可給予愛心。isPressed === true && reduceCondition
let loveValue = 0;
function giveLove(event) {
    
  // 時間紀錄戳為10之倍數時才可給予愛心  
  const reduceCondition = Math.round(event.timeStamp) % 10 === 0;
  if (isPressed === true && reduceCondition) {
    showLoveBubble(square, event);
    loveValue++;
  }
}
其中術名giveLove中,有另一術名為showLoveBubble,其用為顯示予以小七之愛之具現化,但此術非本篇之重點,故不另註釋。
放開鼠輩點按時發生mouseup事件,isPressed變更為false,並將功德量顯示於總功德量顯示處。
function getTotalLove() {
  isPressed = false;
  totalLove.textContent = `目前功德量: ${loveValue}點`;
}
完成簡易之愛鼠祭壇。
另可參考github上紀錄之完整術式,當功德量超過100點時,可超度吾之愛鼠,善哉善哉。
https://github.com/CReticulata/2024ithome/tree/main/Day04
鼠輩:滑鼠
操術:coding
函式之術:function
術式:source code